<template>
	<view class="page-root" :style="pageStyle">
		<message-view ref="message"></message-view>
		<view class="page-head">
			<slot name="head">
				<custom-nav-bar :title="title" :title-align="titleAlign" :text-style="_textStyle" :left-buttons="leftButtons" :nav-background-color="_navBackgroundColor" :statusbar-color="statusbarColor" :float="float" :shadow="shadow" :border-bottom-color="borderBottomColor"></custom-nav-bar>
			</slot>
		</view>
		<view class="page-content" id="custom-page__content" :style="contentBackground">
			<slot>
				<slot name="page">
					<common-list-view ref="list" class="scroll-content" :has-no-data-holder="hasNoDataHolder" :guide-observer-id="guideObserverId" :enable-load-more="enableLoadMore" @listinit="onListInit($event)" 
					:enable-refresh="enableRefresh" @giudeviewintersectionchange="onGiudeViewIntersectionChange($event)" :firstLoad="firstLoad">
						<template #content>
							<slot name="content" :datas="listData"></slot>
						</template>
					</common-list-view>
				</slot>
			</slot>
		</view>
		
		<view class="page-footer">
			<slot name="foot">
				<template v-if="largeIndex >= 0">
					<view v-if="ensureTab && ensureTab.list && ensureTab.list.length > 1 && isTabPage" :class="['bottom-tab-bar', {'bottom-tab-bar-shadow':ensureTab.shadow}]">
						<template v-for="(item, index) in ensureTab.list" :key="index">
							<view v-if="item.large" class="large-tab-item" @click="onTabItemTap(item, index, $event)">
								<view class="large-tab-item-bottom-bg"></view>
								<view class="large-tab-item-circle-wrapper">
									<view class="large-tab-item-circle">
										<image class="large-tab-icon" :src="tabIndex === index ? item.selectedIconPath:item.iconPath"/>
										<text class="large-tab-text">发布</text>
									</view>
								</view>
							</view>
							<view v-else :class="['tab-item', {'prev': index == largeIndex - 1, 'next': index == largeIndex + 1}]" @click="onTabItemTap(item, index, $event)" :style="{background: 'white'}">
								<image class="tab-icon" :src="tabIndex === index ? item.selectedIconPath:item.iconPath" :style="tabIconStyle" mode="aspectFit"></image>
								<text :style="[tabTextStyle, {color: tabIndex === index ? ensureTab.selectedColor:ensureTab.color}]">{{item.text}}</text>
							</view>
						</template>
					</view>
					
				</template>
				<template v-else>
					<view v-if="ensureTab && ensureTab.list && ensureTab.list.length > 1 && isTabPage" :class="['bottom-tab-bar', {'bottom-tab-bar-shadow':ensureTab.shadow}]" :style="tabBarStyle">
						<view v-for="(item, index) in ensureTab.list" :key="index" class="tab-item" @click="onTabItemTap(item, index, $event)">
							<image class="tab-icon" :src="tabIndex === index ? item.selectedIconPath:item.iconPath" :style="tabIconStyle" mode="aspectFit"></image>
							<text :style="[tabTextStyle, {color: tabIndex === index ? ensureTab.selectedColor:ensureTab.color}]">{{item.text}}</text>
						</view>
					</view>
				</template>
			</slot>
		</view>
		
		<view class="safe-area-bottom-insets" :style="safeAreaBottomInsetsStyle"></view>
		<view class="popup-container"><slot name="popup"></slot></view>
	</view>
</template>

<script>
	import { navigationBarOptions, tabBar } from '../../global/global.js'
	import { interceptorResponse } from "../../http/http_interceptor.js"
	import { isPromise } from "../../utils/utils.js"
	
	export default {
		name:"custom-page",
		props: {
			title: {
				type: String,
				default: navigationBarOptions && navigationBarOptions.navigationBarTitle ? navigationBarOptions.navigationBarTitle:""
			},
			titleAlign: {
				type: String,
				default: navigationBarOptions && navigationBarOptions.navigationBarTitleAlign ? navigationBarOptions.navigationBarTitleAlign:"left",
				validator: (val) => {
					if (val === "center" || val === "left") {
						return true
					} else {
						throw new Error("custom-nav-bar 组件的 titleAlign 属性的值只能取 'left' 或者 'center'。")
					}
				}
			},
			textStyle: {
				type: String,
				default: navigationBarOptions && navigationBarOptions.navigationBarTextStyle ? navigationBarOptions.navigationBarTextStyle:"black",
				validator: (val) => {
					if(val === "black" || val === "white") {
						uni.setNavigationBarColor({
							frontColor: val === "black" ? "#000000":"#ffffff",
							backgroundColor: "transparent"
						})
						return true
					} else {
						throw new Error("custom-nav-bar 组件的 navigationBarTextStyle 属性的值只能取 'black' 或者 'white'。")
					}
				}
			},
			leftButtons: {
				type: Array,
				default: navigationBarOptions && navigationBarOptions.leftButtons ? navigationBarOptions.leftButtons:[],
				validator: (val) => {
					if(!val) {
						val = []
					}
					if(val.length > 2) {
						throw new Error("custom-nav-bar 组件的 leftButton数量不能超过两个。")
					}
					return true
				}
			},
			statusbarColor: {
				type: String,
				default: navigationBarOptions && navigationBarOptions.statusbarColor ? navigationBarOptions.statusbarColor:"white"
			},
			navBackgroundColor: {
				type: String,
				default: navigationBarOptions && navigationBarOptions.navigationBarBackgroundColor ? navigationBarOptions.navigationBarBackgroundColor:"white"
			},
			float: {
				type: Boolean,
				default: navigationBarOptions ? navigationBarOptions.float:false
			},
			shadow: {
				type: Boolean,
				default: navigationBarOptions ? navigationBarOptions.shadow:false
			},
			backgroundColor: {
				type: String,
				default: navigationBarOptions && navigationBarOptions.backgroundColor ? navigationBarOptions.backgroundColor:"white"
			},
			tabBar: {
				type: Object,
				default: function() {
					return tabBar ? tabBar:{
						backgroundColor: "white",
						shadow: false,
						selectedColor: "red",
						color: "black",
						height: 50,
						spacing: 3,
						fontSize: 10,
						iconHeight: 24,
						list: []
					}
				}
			},
			enableLoadMore: {
				type: Boolean,
				default: false
			},
			enableRefresh: {
				type: Boolean,
				default: false
			},
			guideObserverId: {
				type: String,
				default: ''
			},
			contentBackground: {
				type: String,
				default: '',
			},
			backgroundImage: {
				type: String,
				default: '',
			},
			borderBottomColor: {
				type: String,
				default: navigationBarOptions ? navigationBarOptions.borderBottomColor:"transparent"
			},
			//是否显示空数据占位
			hasNoDataHolder: {
				type: Boolean,
				default: false
			},
			firstLoad: {
				type: Boolean,
				default: true
			}
		},
		watch: {
			textStyle(newVal, oldVal) {
				this.$nextTick(() => {
					this._textStyle = newVal
				})
			},
			navBackgroundColor(newVal, oldVal) {
				this.$nextTick(() => {
					this._navBackgroundColor = newVal
				})
			}
		},
		computed: {
			ensureTab: function() {
				let tabBar = undefined
				
				let pages = getCurrentPages()
				let currentPage = null
				if(pages && pages.length > 0) {
					currentPage = pages[pages.length - 1]
				}
				if(currentPage && currentPage.$vm) {
					tabBar = currentPage.$vm.tabBar
				}
				
				return tabBar || this.tabBar || {}
			},
			pageStyle: function() {
				return {
					"--navgation-bar-height": this.navgationBarHeight + 'px',
					"--bottom-safe-area-insets": this.bottomSafeAreaInsets + 'px',
					"--content-height": this.contentHeight + 'px',
					"--capsule-menu-horizontal-gap": this.horizontalMenuGap + 'px',
					"--capsule-menu-top": this.capsuleMenuTop + 'px',
					"background": this.backgroundColor,
					"--capsule-menu-width": this.menuWidth + "px",
					"--capsule-menu-height": this.menuHeight + "px",
				}
			},
			tabBarStyle: function() {
				return {
					backgroundColor: this.ensureTab.backgroundColor,
					height: this.ensureTab.height + 'px'
				}
			},
			tabIconStyle: function() {
				return {
					// height: this.ensureTab.iconHeight + 'px'
				}
			},
			tabTextStyle: function() {
				return {
					marginTop: this.ensureTab.spacing + 'px',
					fontSize: this.ensureTab.fontSize + 'px'
				}
			},
			safeAreaBottomInsetsStyle: function() {
				return {
					// height: this.bottomSafeAreaInsets + 'px', 
					backgroundColor: this.isTabPage ? this.ensureTab.backgroundColor:this.backgroundColor
				}
			},
			isTabPage: function() {
				let pages = getCurrentPages()
				let currentPage = pages[pages.length - 1]
				let route = currentPage && currentPage.route ? currentPage.route:"" 
				let tabList = this.ensureTab.list
				if(route && tabList) {
					for(let i=0; i<tabList.length; i++) {
						let routerType = tabList[i].routerType || "switch"
						if(route === tabList[i].pagePath && routerType == "switch") {
							return true
						}
					}
				}
				return false
			},
			tabIndex: function() {
				let pages = getCurrentPages()
				let currentPage = pages[pages.length - 1]
				let route = currentPage && currentPage.route ? currentPage.route:"" 
				let tabList = this.ensureTab.list
				if(route && tabList) {
					for(let i=0; i<tabList.length; i++) {
						if(route === tabList[i].pagePath) {
							return i
						}
					}
				}
				return 0
			},
			largeIndex() {
				let tabList = this.ensureTab.list
				let largeIndex = -1
				if(tabList) {
					for(let i=0; i<tabList.length; i++) {
						if(tabList[i].large) {
							largeIndex = i
							break
						}
					}
				}
				return largeIndex
			}
		},
		data() {
			return {
				navgationBarHeight: 0,
				bottomSafeAreaInsets: 0,
				contentHeight: 0,
				listData: [],
				_textStyle: this.textStyle,
				_navBackgroundColor: this.navBackgroundColor,
				horizontalMenuGap: 0,
				capsuleMenuTop: 0
			};
		},
		beforeCreate: function() {
			let pages = getCurrentPages()
			let currentPage = null
			if(pages && pages.length > 0) {
				currentPage = pages[pages.length - 1]
			}
			if(currentPage) {
				currentPage.$customPage = this
			}
		},
		created: function() {
			// #ifdef MP
			let { top, width, height, right } = uni.getMenuButtonBoundingClientRect()
			let { statusBarHeight, safeAreaInsets, bottomSafeHeight, screenWidth } = uni.getSystemInfoSync()
			this.navgationBarHeight = statusBarHeight + Math.max(44, 2*(top - statusBarHeight) + height)
			this.bottomSafeAreaInsets = safeAreaInsets ? safeAreaInsets.bottom:bottomSafeHeight
			this.horizontalMenuGap = screenWidth - right
			this.capsuleMenuTop = top
			this.menuWidth = width
			this.menuHeight = height
			
			const query = uni.createSelectorQuery().in(this);
			query.select('#custom-page__content').boundingClientRect(data => {
			  this.contentHeight = data && data.height ? data.height:0
			}).exec();
			// #endif
			
			// #ifdef WEB
			this.navgationBarHeight = 44
			this.bottomSafeAreaInsets = 0
			this.horizontalMenuGap = 7
			this.capsuleMenuTop = 6
			this.menuWidth = 87
			this.menuHeight = 32
			// #endif
			
			// #ifdef APP-PLUS
			let { statusBarHeight } = uni.getSystemInfoSync()
			this.navgationBarHeight = 44 + statusBarHeight
			this.bottomSafeAreaInsets = 0
			this.horizontalMenuGap = 7
			this.capsuleMenuTop = statusBarHeight + 6
			this.menuWidth = 87
			this.menuHeight = 32
			// #endif
		},
		methods: {
			onTabItemTap: function(item, index, event) {
				console.log(item)
				if(item.author) {
					let checkLoginPromise = this.requestCenter.checkLogin ? this.requestCenter.checkLogin():null
					if(isPromise(checkLoginPromise)) {
						// checkLoginPromise
						// 	.catch(reason => {
						// 		reason.backPage = item.pagePath
						// 		reason.backType = "redirect"
						// 		return interceptorResponse(reason, null, this.requestCenter, true)
						// 	})
						// 	.then(res => {
						// 		this.switchTab(item.pagePath);
						// 		return Promise.resolve(res)
						// 	})
						// 	.catch(reason => {
						// 		reason.backPage = item.pagePath
						// 		reason.backType = "redirect"
						// 		return Promise.reject(reason)
						// 	})
						// 	.finally(() => uni.hideLoading())
						this.requestCenter.interceptor(() => {
							return checkLoginPromise
						}, {showLoading:true, author: false, backPage: item.pagePath, backType: "redirect"})
						.then(res => {
							this.switchTab(item.pagePath, item.routerType);
							return Promise.resolve()
						})
					} else {
						this.switchTab(item.pagePath, item.routerType);
					}
				} else {
					this.switchTab(item.pagePath, item.routerType);
				}
			},
			
			switchTab: function(pagePath = "pages/index/index", routerType = "switch") {
				if(pagePath.startsWith("/")) {
					pagePath = pagePath.substring(1)
				}
				
				let pages = getCurrentPages()
				let currentPage = null
				if(pages && pages.length > 0) {
					currentPage = pages[pages.length - 1]
				}
				if(currentPage) {
					let route = currentPage.route || ""
					
					if(route == pagePath) {
						return
					}
				}
				
				if(routerType == "switch") {
					uni.switchTab({
						url: "/" + pagePath,
						fail: (err) => {
							uni.reLaunch({
								url: "/" + pagePath,
							})
						} 
					})
				} else {
					uni.navigateTo({
						url: "/" + pagePath
					})
				}
			},
			
			showMessage: function(options) {
				this.$refs.message.isShow = true
				if(!options.type) {
					options.type = "other"
				}
				if(options.type === 'error') {
					this.$refs.message.tips = options.message ? options.message:"发生了一个未知错误，请联系管理员处理..."
				} else {
					this.$refs.message.tips = options.message ? options.message:"empty message"
				}
				this.$refs.message.messageType = options.type
				let timer = setTimeout(() => {
					this.$refs.message.isShow = false
					clearTimeout(timer)
					if(options.complete) {
						options.complete()
					}
				}, options.duration ? options.duration:3000)
			},
			
			onListInit: function(event) {
				this.$emit("listinit", {target: event.target})
			},
			
			setListData: function(datas) {
				this.listData = datas
			},
			
			getListData: function() {
				return this.listData
			},
			
			triggerLoadData: function({start = 1, pageSize = 20, showLoading = false} = {}) {
				this.$nextTick(() => {
					let listView = this.$refs["list"]
					if(listView) {
						listView.triggerLoadData({start: start, pageSize: pageSize, showLoading: showLoading})
					}
				})
			},
			
			onGiudeViewIntersectionChange: function(event) {
				if(event.intersection) {
					this._textStyle = "black"
					this._navBackgroundColor = "white"
				} else {
					this._textStyle = this.textStyle
					this._navBackgroundColor = this.navBackgroundColor
				}
				this.$emit("giudeviewintersectionchange", event)
			}
		}
	}
</script>

<style scoped>
	.page-root {
		display: flex;
		flex-direction: column;
		width: 100vw;
		height: 100vh;
	}
	
	.page-head {
		flex-shrink: 0;
	}
	
	.page-content {
		flex: 1;
		overflow: hidden;
		background-size: cover;
		background-repeat: no-repeat;
		background-position: center center;
	}
	
	.scroll-content {
		height: 100%;
	}
	
	.safe-area-bottom-insets {
		flex-shrink: 0;
		height: constant(safe-area-inset-bottom);
		height: env(safe-area-inset-bottom);
		z-index: 9999;
	}
	
	.bottom-tab-bar {
		width: 100vw;
		height: 50px;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-around;
		position: relative;
	}
	
	.bottom-tab-bar-bg {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
	}
	
	.bottom-tab-bar-shadow {
		box-shadow: 0px -3px 3px -3px #00000017;
	}
	
	.tab-icon {
		width: 24px;
		height: 24px;
	}
	
	.tab-item {
		flex: 1;
		flex-shrink: 0;
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		box-sizing: border-box;
	}
	
	.tab-item.prev {
		position: relative;
		border-top-right-radius: 20px;
		box-shadow: 50px 69px 73px 50px #00000017;

	}
	
	.tab-item.next {
		position: relative;
		border-top-left-radius: 20px;
		box-shadow: 60px 69px 73px 50px #00000017;

	}
	
	.large-tab-icon {
		width: 14px;
		height: 14px;
	}
	
	.large-tab-text {
		font-size: 9px;
		font-weight: 500;
		color: #FFFFFF;
		margin-top: 2px;
	}
	
	.large-tab-item {
		width: 50px;
		height: 50px;
		display: flex;
		flex-direction: row;
		align-items: stretch;
		justify-content: center;
		position: relative;
	}
	
	.large-tab-item-circle-wrapper {
		width: 50px;
		height: 50px;
		border-radius: 25px;
		margin-top: -5px;
		position: relative;
		z-index: 10;
		border: 5px solid transparent;
		box-sizing: border-box;
		box-shadow: 0 15px 4px 4px white;

	}
	
	.large-tab-item-circle {
		width: 40px;
		height: 40px;
		background: linear-gradient(180deg, #FED558, #F8A028);
		border-radius: 20px;
		box-sizing: border-box;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}
	
	.large-tab-item-bottom-bg {
		position: absolute;
		width: 100%;
		height: 50%;
		bottom: 0;
		left: 0;
	}
	
	.popup-container {
		z-index: 9999;
	}
	
	.page-footer {
		z-index: 9999;
	}
</style>